package com.mocchira.music.radio;

import java.io.File;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.Map;
import java.util.WeakHashMap;

import org.json.JSONArray;
import org.json.JSONObject;

import android.content.Context;
import android.util.Log;
import android.widget.Toast;

public class HotTagsManager implements IDownloadListener {
    private boolean isExecuting = false;
    private boolean isSelectableExecuting = false;
    private Context ctx;
    private DownloadManager dlManager;
    private File tagIdxFile;
    private File tagSelectableFile;
    private Map<String, File> artistIdxFile = new WeakHashMap<String, File>();
    private JSONArray tagJson = null;
    private JSONArray selectableJson = null;
    private Map<String, JSONArray> artistJson = new WeakHashMap<String, JSONArray>();
    private static HotTagsManager manager = null;
    private static final long HOT_EXPIRE = 3600 * 12 * 1000;
    private static final String HOT_IDX_FNAME = "idx.json";
    private static final String HOT_SELECTABLE_FNAME = "selectable.json";
    private static final String HOT_URL_BASE = "http://shopping.mocchira.com/selected/";
    private static final String HOT_TAG_IDX_URL = HOT_URL_BASE + HOT_IDX_FNAME;
    private static final String HOT_TAG_SELECTABLE_URL = HOT_URL_BASE + HOT_SELECTABLE_FNAME;
    
    public static HotTagsManager getInstance(Context ctx) {
        if (manager == null) {
            manager = new HotTagsManager(ctx);
        }
        return manager;
    }
    private HotTagsManager(Context ctx) {
        this.ctx = ctx;
        dlManager = new DownloadManager(ctx, this);
        tagIdxFile = new File(ctx.getFilesDir(), "selected__tag__.json");
        tagSelectableFile = new File(ctx.getFilesDir(), "selectable__tag__.json");
    }
    private boolean isExpire(File file) {
        if (file == null || !file.canRead())
            return true;
        long lastMod = file.lastModified();
        return ((System.currentTimeMillis() - lastMod) > HOT_EXPIRE);
    }
    //@note string including return values is encoded as urlencode utf-8
    public JSONArray getHotTags() {
        if (isExpire(tagIdxFile)) {
            if (isExecuting) return null;
            isExecuting = true;
            dlManager.enqueue(HOT_TAG_IDX_URL);
            return null;
        } else if (tagJson == null) {
            try {
                String hotStr = FileUtil.getContents(tagIdxFile);
                JSONObject root = new JSONObject(hotStr);
                tagJson = root.getJSONArray("tags");
            } catch (Exception ex) {
                Log.e("fmr", ex.getMessage(), ex);
                dlManager.enqueue(HOT_TAG_IDX_URL);
                return null;
            }
        }
        return tagJson;
    }
  //@note string including return values is encoded as urlencode utf-8
    public final JSONArray getSelectableTags() {
        if (isExpire(tagSelectableFile)) {
            if (isSelectableExecuting) return null;
            isSelectableExecuting = true;
            dlManager.enqueue(HOT_TAG_SELECTABLE_URL);
            return null;
        } else if (selectableJson == null) {
            try {
                String selStr = FileUtil.getContents(tagSelectableFile);
                JSONObject root = new JSONObject(selStr);
                selectableJson = root.getJSONArray("tags");
            } catch (Exception ex) {
                Log.e("fmr", ex.getMessage(), ex);
                dlManager.enqueue(HOT_TAG_SELECTABLE_URL);
                return null;
            }
        }
        return selectableJson;
    }
    private String genArtistsUrl(String tag) {
        String url = HOT_URL_BASE;
        String encTag = "";
        try {
            encTag = URLEncoder.encode(tag, "UTF-8");
        } catch (Exception ex){};
        url += encTag + ".json";
        return url;
    }
    //@note string including return values is encoded as urlencode utf-8
    public JSONArray getHotArtistsByTag(String tag) {
        File file = artistIdxFile.get(tag);
        if (file == null) {
            file = new File(ctx.getFilesDir(), "selected__" + tag);
            artistIdxFile.put(tag, file);
        }
        if (isExpire(file)) {
            if (isExecuting) return null;
            isExecuting = true;
            String url = genArtistsUrl(tag);
            dlManager.enqueue(url);
            return null;
        } else if (artistJson.get(tag) == null) {
            try {
                String hotStr = FileUtil.getContents(file);
                JSONObject root = new JSONObject(hotStr);
                artistJson.put(tag, root.getJSONArray("artists"));
            } catch (Exception ex) {
                String url = genArtistsUrl(tag);
                dlManager.enqueue(url);
                Log.e("fmr", ex.getMessage(), ex);
                return null;
            }
        }
        return artistJson.get(tag);
    }
    @Override
    public void onComplete(String url, File tmpFile, Exception ex) {
        isExecuting = false;
        if (ex != null) {
            isSelectableExecuting = false;
            Toast.makeText(ctx, R.string.msg_network_err, Toast.LENGTH_LONG).show();
        } else {
            if (url.equals(HOT_TAG_IDX_URL)) {
                tmpFile.renameTo(tagIdxFile);
                getHotTags();
            } else if (url.equals(HOT_TAG_SELECTABLE_URL)) {
                isSelectableExecuting = false;
                tmpFile.renameTo(tagSelectableFile);
                getSelectableTags();
            } else {
                String[] token = url.split("/");
                String decTag = "";
                try {
                    decTag = URLDecoder.decode(token[4], "UTF-8");
                    token = decTag.split("\\.");
                    decTag = token[0];
                } catch (Exception nex){};
                File dst = artistIdxFile.get(decTag);
                tmpFile.renameTo(dst);
                getHotArtistsByTag(decTag);
            }
        }
    }

}
